#pragma once

#include <string>
#include "Channel.hpp"
#include "EventLoop.hpp"
#include "Buffer.hpp"
#include "Protocol.hpp"

class TcpConnection
{
public:
    TcpConnection(int fd, EventLoop *evLoop)
        : _evLoop(evLoop)
    {
        _name = "TcpConnection-" + std::to_string(fd);
        _readBuf = new Buffer(1024);
        _writeBuf = new Buffer(1024);
        _channel = new Channel(fd, ReadEvent, ProcessRead, ProcessWrite, this);
    }
    ~TcpConnection()
    {
        if (_channel)
        {
            _evLoop->_channelMap[_channel->_fd] = nullptr; // 将对应关系进行清空
            delete _channel;
        }
        if (_readBuf)
            delete _readBuf;
        if (_writeBuf)
            delete _writeBuf;
    }
    void Run()
    {
        _evLoop->addTask(_channel, ADD);
    }

private:
    static int ProcessRead(void *arg)
    {
        // LOG(INFO) << arg << std::endl;
        TcpConnection *tcpConnection = static_cast<TcpConnection *>(arg);
        // LOG(INFO) << tcpConnection << std::endl;
        int sz = tcpConnection->_readBuf->ReadSocket(tcpConnection->_channel->_fd);
        // LOG(INFO) << sz << std::endl;
        Http *http = new Http;
        if (sz > 0)
        {
#ifdef MSG_SEND_AUTO
            // 使能写事件 让底层io模型能够检测fd的写事件 写事件回调不是立即触发
            tcpConnection->_channel->EnableWriteEvent(true);
            tcpConnection->_evLoop->addTask(tcpConnection->_channel, MODIFY);
#endif
            // 分析请求
            http->ParseHttpRequest(tcpConnection->_readBuf);
            // 处理请求
            http->ProcessHttpRequest();
            // 构建响应
            http->BuildHttpResponse(tcpConnection->_writeBuf, tcpConnection->_channel->_fd);
        }
        delete http;
#ifndef MSG_SEND_AUTO
        // 断开连接
        tcpConnection->_evLoop->addTask(tcpConnection->_channel, DELETE);
        delete tcpConnection;
#endif
        return 0;
    }
    static int ProcessWrite(void *arg)
    {
        TcpConnection *tcpConnection = (TcpConnection *)arg;
        // 发送数据
        int sz = tcpConnection->_writeBuf->SendData(tcpConnection->_channel->_fd);
        if (sz > 0)
        {
            // 判断写缓冲区数据是否全部发送了，发送完了就断开
            if (tcpConnection->_writeBuf->WriteAbleSize() == 0)
            {
                // 断开连接
                tcpConnection->_evLoop->addTask(tcpConnection->_channel, DELETE);
                delete tcpConnection;
            }
        }

        return 0;
    }

private:
    std::string _name;
    Channel *_channel;
    EventLoop *_evLoop;
    Buffer *_readBuf;
    Buffer *_writeBuf;
};